package general;

import java.util.Arrays;
import java.util.List;

public class Utility {
	// ---------------- hex-byte-conversion -------------------

	/**
	 * builds a String as hex-representation of a byte-array
	 */
	public static String bytesToHex(byte[] bytes) {
		char[] hexChars = new char[bytes.length * 3 - 1];
		int v;
		for (int i = 0; i < bytes.length; i++) {
			v = bytes[i] & 0xFF;
			hexChars[i * 3] = Utility.HEX_ARRAY[v >>> 4];
			hexChars[i * 3 + 1] = Utility.HEX_ARRAY[v & 0x0F];
			if (i < bytes.length - 1) {
				hexChars[i * 3 + 2] = ' ';
			}
		}
		return new String(hexChars);
	}

	public static final Character[] HEX_ARRAY = { '0', '1', '2', '3', '4', '5',
			'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
	static final List<Character> HEX_LIST = Arrays.asList(Utility.HEX_ARRAY);

	/**
	 * builds a byte-array for a string with hex-representation
	 */
	public static byte[] hexToBytes(String hex) {
		String cleanedHex = hex.toLowerCase().replaceAll("\\s", "");
		return Utility.hexStringToByteArray(cleanedHex);
	}

	private static byte[] hexStringToByteArray(String hex) {
		int len = hex.length();
		byte[] data = new byte[len / 2];
		for (int i = 0; i < len; i += 2) {
			data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character
					.digit(hex.charAt(i + 1), 16));
		}
		return data;
	}

	// --------------- split-merge-conversion ----------------
	/**
	 * merges an array of arrays to one single array containing the content of
	 * all arrays appended onto each other
	 */
	public static int[] mergeData(int[][] dataChunks) {
		int sizeOfNewArray = 0;
		for (int[] dataChunk : dataChunks) {
			sizeOfNewArray += dataChunk.length;
		}
		int[] mergedData = new int[sizeOfNewArray];
		int lastOffset = 0;
		for (int[] dataChunk : dataChunks) {
			System.arraycopy(dataChunk, 0, mergedData, lastOffset,
					dataChunk.length);
			lastOffset += dataChunk.length;
		}
		return mergedData;
	}

	public static int BLOCK_LENGTH = 4;

	/**
	 * splits a given array into an array of arrays of length
	 * <code>BLOCK_LENGTH</code>
	 */
	public static int[][] splitData(int[] data) {
		int[][] splitData = new int[data.length / BLOCK_LENGTH][BLOCK_LENGTH];
		for (int i = 0; i < splitData.length; i++) {
			System.arraycopy(data, BLOCK_LENGTH * i, splitData[i], 0,
					BLOCK_LENGTH);
		}
		return splitData;
	}

}
